package com.retry.task.core.model;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.retry.task.core.constants.SelectorExectorEnum;
import org.springframework.beans.BeanUtils;

/**
 * @author gao.gwq
 * @version 1.0
 * @date 2022/5/1  21:54
 * @Description TODO
 */
public class RetryTaskDTO extends BaseDTO implements Serializable {
    private static final long serialVersionUID = 1012673926571386138L;

    private Integer isTest;

    /**
     * 所使用的项目名称
     */
    private String projectName;
    /**
     * 重试任务的描述
     */
    private String taskDesc;

    /**
     * 重试任务的bean 名称
     */
    private String taskName;

    /**
     * 类型 0 重试任务 默认是重试任务
     * 1 定时任务
     */
    private int taskType;

    /**
     * 执行类型 0 按照intervalSecond 间隔时间
     * 1 cron表达式
     */
    private int executeType;

    /**
     * 是否异步 0 异步
     * 1 同步
     */
    private int isAsync;

    /**
     * 是否广播 0单机执行
     * 1 广播
     */
    private int isBroadcast;

    /**
     * 执行时间间隔 秒
     */
    private Integer intervalSecond;

    /**
     * 初次创建延迟时间
     */
    private Integer delayTime;
    /**
     * 重试次数>1 小于100
     */
    private Integer retryNum;

    private String creatorName;

    private String corn;

    /**
     * 任务预计最大执行时间
     */
    private Integer maxExecuteTime;
    private String creatorId;

    /**
     * 异常通知人
     */
    private String warningPerson;

    /**
     * 通知类型
     */
    private String warningType;

    private String parameters;

    private String creatorIp;

    private String token;

    private AttributeModel attributeModel;

    public AttributeModel getAttributeModel() {
        return attributeModel;
    }

    private void setAttributeModel(AttributeModel attributeModel) {
        this.attributeModel = attributeModel;
    }

    private String targetExecuteIp;

    private String selectorType;

    /**
     * 下次执行时间
     */
    private Date nextPlanTime;

    private Long currentLogId;


    private Integer status;


    public Long getCurrentLogId() {
        return currentLogId;
    }

    public void setCurrentLogId(Long currentLogId) {
        this.currentLogId = currentLogId;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    public Date getNextPlanTime() {
        return nextPlanTime;
    }

    public void setNextPlanTime(Date nextPlanTime) {
        this.nextPlanTime = nextPlanTime;
    }

    public String getSelectorType() {
        return selectorType;
    }

    public void setSelectorType(String selectorType) {
        this.selectorType = selectorType;
    }


    public String getTargetExecuteIp() {
        return targetExecuteIp;
    }

    public void setTargetExecuteIp(String targetExecuteIp) {
        this.targetExecuteIp = targetExecuteIp;
    }


    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }

    public Integer getIsTest() {
        return isTest;
    }

    public void setIsTest(Integer isTest) {
        this.isTest = isTest;
    }

    public String getProjectName() {
        return projectName;
    }

    public void setProjectName(String projectName) {
        this.projectName = projectName;
    }

    public String getTaskDesc() {
        return taskDesc;
    }

    public void setTaskDesc(String taskDesc) {
        this.taskDesc = taskDesc;
    }

    public String getTaskName() {
        return taskName;
    }

    public void setTaskName(String taskName) {
        this.taskName = taskName;
    }

    public int getTaskType() {
        return taskType;
    }

    public void setTaskType(int taskType) {
        this.taskType = taskType;
    }

    public int getExecuteType() {
        return executeType;
    }

    public void setExecuteType(int executeType) {
        this.executeType = executeType;
    }

    public int getIsAsync() {
        return isAsync;
    }

    public void setIsAsync(int isAsync) {
        this.isAsync = isAsync;
    }

    public int getIsBroadcast() {
        return isBroadcast;
    }

    public void setIsBroadcast(int isBroadcast) {
        this.isBroadcast = isBroadcast;
    }

    public Integer getIntervalSecond() {
        return intervalSecond;
    }

    public void setIntervalSecond(Integer intervalSecond) {
        this.intervalSecond = intervalSecond;
    }

    public Integer getDelayTime() {
        return delayTime;
    }

    public void setDelayTime(Integer delayTime) {
        this.delayTime = delayTime;
    }

    public Integer getRetryNum() {
        return retryNum;
    }

    public void setRetryNum(Integer retryNum) {
        this.retryNum = retryNum;
    }

    public String getCreatorName() {
        return creatorName;
    }

    public void setCreatorName(String creatorName) {
        this.creatorName = creatorName;
    }

    public String getCorn() {
        return corn;
    }

    public void setCorn(String corn) {
        this.corn = corn;
    }

    public Integer getMaxExecuteTime() {
        return maxExecuteTime;
    }

    public void setMaxExecuteTime(Integer maxExecuteTime) {
        this.maxExecuteTime = maxExecuteTime;
    }

    public String getCreatorId() {
        return creatorId;
    }

    public void setCreatorId(String creatorId) {
        this.creatorId = creatorId;
    }

    public String getWarningPerson() {
        return warningPerson;
    }

    public void setWarningPerson(String warningPerson) {
        this.warningPerson = warningPerson;
    }

    public String getWarningType() {
        return warningType;
    }

    public void setWarningType(String warningType) {
        this.warningType = warningType;
    }

    public String getParameters() {
        return parameters;
    }

    public void setParameters(String parameters) {
        this.parameters = parameters;
    }

    public String getCreatorIp() {
        return creatorIp;
    }

    public void setCreatorIp(String creatorIp) {
        this.creatorIp = creatorIp;
    }

    public String getTargetExecutorIp() {
        return targetExecutorIp;
    }

    public void setTargetExecutorIp(String targetExecutorIp) {
        this.targetExecutorIp = targetExecutorIp;
    }

    /**
     * 执行执行机器的ip
     */
    private String targetExecutorIp;

    private RetryTaskDTO() {

    }

    public static Builder createBuilder() {
        return new Builder();
    }

    public static class Builder {

        private Integer isTest;

        /**
         * 异常通知人
         */
        private String warningPerson;

        /**
         * 通知类型
         */
        private String warningType;
        /**
         * 所使用的项目名称
         */
        private String projectName;
        /**
         * 重试任务的描述
         */
        private String taskDesc;

        /**
         * 重试任务的bean 名称
         */
        private String taskName;

        /**
         * 类型 0 重试任务 默认是重试任务
         * 1 定时任务
         */
        private int taskType;

        /**
         * 执行类型 0 按照intervalSecond 间隔时间
         * 1 cron表达式
         */
        private int executeType;

        private String targetExecuteIp;

        /**
         * 是否异步 0 异步
         * 1 同步
         */
        private int isAsync;

        /**
         * 是否广播 0单机执行
         * 1 广播
         */
        private int isBroadcast;

        /**
         * 执行时间间隔 秒
         */
        private Integer intervalSecond;

        /**
         * 初次创建延迟时间
         */
        private Integer delayTime;
        /**
         * 重试次数>1 小于100
         */
        private Integer retryNum;

        private String creatorName;

        private String corn;

        /**
         * 任务预计最大执行时间
         */
        private Integer maxExecuteTime;
        private String creatorId;

        private String parameters;

        private String creatorIp;

        private String attribute;
        //RANDOM,//随机
        //LAST_HEART,//最新一次心跳
        //POLLING;//轮询
        private String selectorType;

        public Builder selectorType(String selectorType) {
            this.selectorType = selectorType;
            return this;
        }

        public Builder targetExecuteIp(String targetExecuteIp) {
            this.targetExecuteIp = targetExecuteIp;
            return this;
        }

        public Builder attribute(String attribute) {
            this.attribute = attribute;
            return this;

        }

        private Builder warningType(String warningType) {
            this.warningType = warningType;
            return this;
        }

        private Builder warningPerson(String warningPerson) {
            this.warningPerson = warningPerson;
            return this;
        }

        private String token;

        public Builder token(String token) {
            this.token = token;
            return this;
        }

        public RetryTaskDTO build() {
            /*RetryTaskDTO retryTaskDTO = new RetryTaskDTO();
            retryTaskDTO.setRetryNum(this.retryNum);
            retryTaskDTO.setIntervalSecond(this.intervalSecond);
            retryTaskDTO.setMaxExecuteTime(this.maxExecuteTime);
            retryTaskDTO.setTaskDesc(this.taskDesc);
            retryTaskDTO.setProjectName(this.projectName);
            retryTaskDTO.setTaskName(this.taskName);
            retryTaskDTO.setCorn(this.corn);
            retryTaskDTO.setExecuteType(this.executeType);
            retryTaskDTO.setIsAsync(this.isAsync);
            retryTaskDTO.setCreatorId(this.creatorId);
            retryTaskDTO.setCreatorName(this.creatorName);
            retryTaskDTO.setMaxExecuteTime(this.maxExecuteTime);
            retryTaskDTO.setDelayTime(this.delayTime);
            retryTaskDTO.setCreatorIp(this.creatorIp);
            retryTaskDTO.setTargetExecutorIp(this.targetExecutorIp);
            retryTaskDTO.setIsBroadcast(this.isBroadcast);
            retryTaskDTO.setWarningPerson(this.warningPerson);
            retryTaskDTO.setWarningType(this.warningType);
            retryTaskDTO.setParameters(this.parameters);
            retryTaskDTO.setAttribute(this.attribute);
            retryTaskDTO.setIsTest(this.isTest);
            retryTaskDTO.setToken(this.token);*/
            return doCreateRetryTaskDTO();
        }

        public Builder isBroadcast(Integer isBroadcast) {
            this.isBroadcast = isBroadcast;
            return this;
        }

        public Builder isAsync(Integer isAsync) {
            this.isAsync = isAsync;
            return this;
        }

        public Builder executeType(Integer executeType) {
            this.executeType = executeType;
            return this;
        }

        public Builder creatorIp(String creatorIp) {
            this.creatorIp = creatorIp;
            return this;
        }

        public Builder parameters(String parameters) {
            this.parameters = parameters;
            return this;
        }

        public Builder creatorId(String creatorId) {
            this.creatorId = creatorId;
            return this;
        }

        public Builder maxExecuteTime(Integer maxExecuteTime) {
            this.maxExecuteTime = maxExecuteTime;
            return this;
        }

        public Builder isTest(Integer isTest) {
            this.isTest = isTest;
            return this;
        }

        public Builder corn(String corn) {
            this.corn = corn;
            return this;
        }

        public Builder projectName(String projectName) {
            this.projectName = projectName;
            return this;
        }

        public Builder creatorName(String creatorName) {
            this.creatorName = creatorName;
            return this;
        }

        public Builder retryNum(Integer retryNum) {
            this.retryNum = retryNum;
            return this;
        }

        public Builder delayTime(Integer intervalSecond) {
            this.delayTime = delayTime;
            return this;
        }

        public Builder intervalSecond(Integer intervalSecond) {
            this.intervalSecond = intervalSecond;
            return this;
        }

        public Builder taskType(Integer taskType) {
            this.taskType = taskType;
            return this;
        }

        public Builder taskName(String taskName) {
            this.taskName = taskName;
            return this;
        }

        public Builder taskDesc(String taskDesc) {
            this.taskDesc = taskDesc;
            return this;
        }

        private RetryTaskDTO doCreateRetryTaskDTO() {
            Method[] methods = RetryTaskDTO.class.getDeclaredMethods();
            Map<String, Method> methodMap = new HashMap<>();
            for (Method method : methods) {
                methodMap.put(method.getName(), method);
            }
            RetryTaskDTO retryTaskDTO = new RetryTaskDTO();
            Field[] fieldArr = this.getClass().getDeclaredFields();
            for (Field field : fieldArr) {
                field.setAccessible(true);
                String fieldName = field.getName();
                fieldName = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
                String setMethodName = "set" + fieldName;
                Method method = methodMap.get(setMethodName);
                if (method == null) {
                    continue;
                }
                try {
                    Object value = field.get(this);
                    method.invoke(retryTaskDTO, value);

                } catch (Exception ex) {

                }

            }
            return retryTaskDTO;
        }
    }

}
